package map.utils;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.script.ScriptException;



import map.beans.owf.OwfDescriptorBean;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.google.common.base.Charsets;
import com.google.common.io.Resources;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;


public class WidgetDataParser {
	private StringBuilder sb;
	private final static String EMPTY = "";
	private final static String OPEN_TAG  = "<script id=\"owfTransport\" type=\"text/javascript\">";
	private final static String CLOSE_TAG = "</script>";
	private final static String WIDGETDATA_REGEX = "widgetData\\s*=(\\s*\\n*\\r*\\t*.+?};)";	
	
	private String html;
	private Document doc;
	
	
	public WidgetDataParser() { 
		sb = new StringBuilder();
	}
	
	public WidgetDataParser(String src) {
		loadHtml(src);
	}
	
	public void loadHtml(String src) {
		boolean isResource = isLocalResource(src);
		
		Document doc;		
		try {
			if (!isResource) {
				doc = Jsoup.connect(src).get();
			} else {
				String html = getResourceText(new File(src).getName());
				doc = Jsoup.parse(html);
			}
			html = (doc.toString());			
			
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}		
		
	}
	
	private boolean isLocalResource(String path) {
		boolean isResource = false;
		try {
			URL url = new URL(path);
			if (url.getProtocol().equalsIgnoreCase("file")) {
				isResource = true;
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		
		return isResource;
	}
	
	public String getScriptById(String id) throws ScriptException {
		return doc.head().select("script#owfTransport").toString();
	}
	
	public String getOwfTransport(String src) throws ScriptException {

		boolean isResource = false;
		try {
			URL url = new URL(src);
			if (url.getProtocol().equalsIgnoreCase("file")) {
				isResource = true;
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}

		Document doc;
		sb = new StringBuilder();
		
		try {
			if (!isResource) {
				doc = Jsoup.connect(src).get();
			} else {
				String html = getResourceText(new File(src).getName());
				doc = Jsoup.parse(html);
			}

			Element head = doc.head();
			Elements elems = head.select("script#owfTransport");			

			sb.append(elems.toString());			
			
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
		return sb.toString();
	}
	
	public String getResourceText(String src) {
		String contents = "";
		try {
			URL url = getClass().getClassLoader().getResource(src);// Resources.getResource(src);// Thread.currentThread().getContextClassLoader().getResource(src);
			contents = Resources.toString(url, Charsets.UTF_8);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return contents;
	}

	public String getWidgetData(String src) {		
		String textOnly = src.replace("\n", "").replace("\r", "").replace("\t", "");
		
		Pattern pattern = Pattern.compile(WIDGETDATA_REGEX);
		Matcher matcher = pattern.matcher(textOnly);
		matcher.find();
		textOnly = new String(matcher.group(1));
//		System.out.println(textOnly);		
//		textOnly = textOnly.replaceAll(REMOVE_WS_NOT_QUOTED, "");
		return textOnly;
	}
	
	public String getWidgetDataAsJsonString() {		
		return getWidgetDataAsJsonString(this.html);
	}
	
	public String getWidgetDataAsJsonString(String src) {		
		String textOnly = getWidgetData(src);
		//textOnly = textOnly.replaceAll(REMOVE_ALL_BEFORE, "");
		//textOnly = textOnly.replaceAll(REMOVE_ALL_AFTER, "");	
		
		if (textOnly.endsWith(";")) {
			textOnly = textOnly.substring(0, textOnly.lastIndexOf(";"));
		}

//		textOnly = textOnly.replaceAll(REMOVE_WS_NOT_QUOTED, "");
		
		return textOnly;
	}	

	
	public OwfDescriptorBean getOwfDescriptorFromHtml() {
		String htmlCopy = "";
		if (this.html.length() > 0) {
			htmlCopy = this.html;
		}
		htmlCopy = removeOwfTransportScriptTag(htmlCopy);				
		
		String widgetData = getWidgetDataAsJsonString(htmlCopy);
		
		GsonBuilder gsonBuilder = new GsonBuilder();
		Gson gson = gsonBuilder.create();
		
		OwfDescriptorBean odb = gson.fromJson(widgetData, OwfDescriptorBean.class);
		
		return odb;
	}
	
	private String removeOwfTransportScriptTag(String src) {
		ArrayList<String> rem = new ArrayList<String>();
		rem.add(OPEN_TAG);
		rem.add(CLOSE_TAG);
		
		return replaceMultiple(src, rem, EMPTY);
		
	}

	/**
	 * @return the html
	 */
	public String getHtml() {
		return html;
	}

	/**
	 * @param html the html to set
	 */
	public void setHtml(String html) {
		this.html = html;
	}

	/**
	 * @return the doc
	 */
	public Document getDoc() {
		return doc;
	}

	/**
	 * @param doc the doc to set
	 */
	public void setDoc(Document doc) {
		this.doc = doc;
	}

	private String replaceMultiple(String src, List<String> removeStrings, String replacementString) {

		for (int i = 0; i < removeStrings.size(); i++) {
			src = src.replace(removeStrings.get(i), replacementString);
		}
		return src;
	}
	
	
}
